package main

import (
	"context"
	"log"
	"time"
)

func main() {
	d15_value()
}

// 1.context.WithCancel 创建一个可以被取消的上下文
func d15_cancel() {
	ctx, cancel := context.WithCancel(context.Background())

	go func() {
		log.Println("cancel begin")
		time.Sleep(1 * time.Second)
		// 取消上下文
		cancel()
		log.Println("cancel end")
	}()

	// 等待上下文取消
	select {
	case <-ctx.Done():
		log.Println("context canceled")
	}
}

// 2.context.WithTimeout 创建一个有超时的上下文
func d15_timeout() {
	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	go func() {
		log.Println("cancel begin")
		time.Sleep(2 * time.Second)
		// 取消上下文
		cancel()
		// 执行不到这行代码
		log.Println("cancel end")
	}()

	// 等待上下文取消
	select {
	case <-ctx.Done():
		log.Println("context Done")
	}
}

// 3.context.WithDeadline 创建一个有截止时间的上下文
func d15_deadline() {
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(1*time.Second))
	go func() {
		log.Println("cancel begin")
		time.Sleep(2 * time.Second)
		// 取消上下文
		cancel()
		// 执行不到这行代码
		log.Println("cancel end")
	}()

	// 等待上下文取消
	select {
	case <-ctx.Done():
		log.Println("context Done")
	}
}

// 4.context.WithValue 创建一个可以携带值的上下文
func d15_value() {
	ctx := context.WithValue(context.Background(), "k1", "v1")
	go func() {
		log.Println("go begin")
		time.Sleep(1 * time.Second)

		v1 := ctx.Value("k1")

		log.Println("go end, value =", v1)
	}()

	select {
	case <-time.After(2 * time.Second):
		log.Println("d15_value Done")
	}

}
